package com.cloud.tsp.service.impl;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.csp.sentinel.util.StringUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cloud.core.util.R;
import com.cloud.core.exception.MyException;
import com.cloud.api.domain.stats.ModelStatsExcel;
import com.cloud.api.domain.stats.QueryAreal;
import com.cloud.api.domain.stats.VehicleRunningData;
import com.cloud.api.domain.stats.VehicleStatsExcel;
import com.cloud.api.domain.sys.SystemRoleDto;
import com.cloud.api.utils.ExcelUtils;
import com.cloud.api.constants.StrVo;
import com.cloud.mybatis.domain.TableDataInfo;
import com.cloud.tsp.mapper.VehicleRunningDataMapper;
import com.cloud.tsp.service.IVehicleRunningDataService;
import org.springframework.beans.BeanUtils;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Service;

import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;

/**
 * <p>
 * OLAP 服务实现类
 * </p>
 *
 * @author haohaibo
 * @since 2023-12-29
 */
@Service("vehicleRunningDataService")
public class VehicleRunningDataServiceImpl extends ServiceImpl<VehicleRunningDataMapper, VehicleRunningData> implements IVehicleRunningDataService {

    @Resource
    private VehicleRunningDataMapper vehicleRunningDataMapper;

    @Resource
    private MessageSource messageSource;

    @Override
    public TableDataInfo<VehicleRunningData> selectVehicleList(QueryAreal para) {
        getDate(para);
//        getPermissions(para);
        Page<VehicleRunningData> page = new Page<>();
        page.setCurrent(para.getPage());
        page.setSize(para.getPageSize());
        IPage<VehicleRunningData> data = vehicleRunningDataMapper.selectVehicleList(page, para);
        handleData(data.getRecords(),para);
        return TableDataInfo.build(data);
    }

    /*public void getPermissions(QueryAreal para){
        para.setDataScope(LoginHelper.getDataScope());
        if (para.getDataScope() == 5){
            R<SystemRoleDto> roleDetail = systemRoleOpenFeignService.getById(new StrVo(LoginHelper.getUserLogin().getRoleId()));
            String[] split = roleDetail.getData().getDeptIds().split(",");
            List<String> deptIds = new ArrayList<>(Arrays.asList(split));
            para.setDeptIds(deptIds);
        }else {
            List<String> list = new ArrayList<>();
            list.add(LoginHelper.getUserLogin().getDeptId());
            para.setDeptIds(list);
        }
    }*/

    private void handleData(List<VehicleRunningData> data,QueryAreal para){
        DecimalFormat df = new DecimalFormat("#0.00");
        df.setRoundingMode(RoundingMode.HALF_UP);
        data.forEach(a -> {
            a.setAccumulativeMileage(a.getAccumulativeMileage() * 0.1);
            a.setRunningMileage(a.getRunningMileage()* 0.1);
            if (a.getAccumulativeMileage().equals(a.getRunningMileage())){
                a.setRunningMileage(0.0);
            }
            a.setRunTime(a.getRunTime()!=null ? (a.getRunTime()/(60 * 60.0)) : null);
            a.setStopDays(para.getDay() - a.getRunDays());
            a.setAveMileage(a.getRunningMileage()!=0.0 ? Double.parseDouble(df.format(a.getRunningMileage()/a.getRunDays())) : 0.0);
            a.setAveSpeed((a.getRunningMileage()!=0.0 && a.getRunTime() != null)? Double.parseDouble(df.format(a.getRunningMileage()/a.getRunTime())) : 0.0);
            a.setAveChargePower(a.getChargePower() != null ? Double.parseDouble(df.format(a.getChargePower()/a.getRunDays())) : null);

            a.setAccumulativeMileage(Double.parseDouble(df.format(a.getAccumulativeMileage())));
            a.setRunningMileage(Double.parseDouble(df.format(a.getRunningMileage())));
            a.setRunTime(a.getRunTime()!=null ? Double.parseDouble(df.format(a.getRunTime())) : null);
            a.setChargeTime(a.getChargeTime()!=null ? Double.parseDouble(df.format(a.getChargeTime()/(60 * 60.0))): 0.0);
            a.setChargePower(a.getChargePower()!=null ? Double.parseDouble(df.format(a.getChargePower())) : null);

            if (StringUtil.isNotBlank(a.getVin())){
                a.setVin(StrUtil.hide(a.getVin(), 8, 11));
            }
            if (StringUtil.isNotBlank(a.getLicenseNumber())){
                if ("oil".equals(a.getVehicleType())){
                    a.setLicenseNumber(StrUtil.hide(a.getLicenseNumber(), 3, 6));
                }else {
                    a.setLicenseNumber(StrUtil.hide(a.getLicenseNumber(), 4, 7));
                }
            }

        });
    }

    public void getDate(QueryAreal para){
        if (para.getStartTime() == null || para.getEndTime() == null){
            para.setStartTime(DateUtil.date(System.currentTimeMillis()));
            para.setEndTime(para.getStartTime());
        }
        int day = (int)DateUtil.between(para.getStartTime(), para.getEndTime(), DateUnit.DAY)  + 1 ;
        if (day > 31){
            throw new MyException("wds.exception.dateRange");
        }
        para.setDay(day);
    }

    @Override
    public TableDataInfo<VehicleRunningData> selectModelList(QueryAreal para) {
        getDate(para);
//        getPermissions(para);
        Page<VehicleRunningData> page = new Page<>();
        page.setCurrent(para.getPage());
        page.setSize(para.getPageSize());
        IPage<VehicleRunningData> data = vehicleRunningDataMapper.selectModelList(page, para);
        handleData(data.getRecords(),para);
        return TableDataInfo.build(data);
    }

    @Override
    public void exportVehicleList(QueryAreal para, HttpServletResponse response) throws IOException {
        Locale locale = LocaleContextHolder.getLocale();
        String fileName = "table.vehicle";
        getDate(para);
//        getPermissions(para);
        List<VehicleRunningData> data = vehicleRunningDataMapper.exportVehicleList(para);
        handleData(data,para);
        List<VehicleStatsExcel> list = new ArrayList<>();
        data.forEach(a -> {
            VehicleStatsExcel vehicleStatsExcel = new VehicleStatsExcel();
            BeanUtils.copyProperties(a,vehicleStatsExcel);
            list.add(vehicleStatsExcel);
        });
        fileName = messageSource.getMessage(fileName, null, fileName, locale);
        ExcelUtils.export(response,fileName,list,VehicleStatsExcel.class);

    }

    @Override
    public void exportModelList(QueryAreal para, HttpServletResponse response) throws IOException {
        Locale locale = LocaleContextHolder.getLocale();
        String fileName = "table.model";
        getDate(para);
//        getPermissions(para);
        List<VehicleRunningData> data = vehicleRunningDataMapper.exportModelList(para);
        handleData(data,para);
        List<ModelStatsExcel> list = new ArrayList<>();
        data.forEach(a -> {
            ModelStatsExcel modelStatsExcel = new ModelStatsExcel();
            BeanUtils.copyProperties(a,modelStatsExcel);
            list.add(modelStatsExcel);
        });
        fileName = messageSource.getMessage(fileName, null, fileName, locale);
        ExcelUtils.export(response,fileName,list,ModelStatsExcel.class);
    }
}
